using System;
using System.IO;

namespace lucere.io.concurrency
{
	/// <summary>
	///<p>Implements <see cref="ILockFactory"></see> using <see cref="System.IO.File.Create(string)"></see>.</p>
	/// <p>If you suspect that this or any other LockFactory is
	/// not working properly in your environment, you can easily
	/// test it by using <see cref="VerifyingLockFactory"></see>, <see cref="ILockVerifyServer"></see> 
	/// and <see cref="LockStressTest"></see>
	/// </p>
	/// </summary>
	public class SimpleFSLockFactory : LockFactory
	{
		private DirectoryInfo _lockDir;

		/// <summary>
		/// Create a SimpleFSLockFactory instance, with null (unset)
		/// lock directory. When you pass this factory to a <see href="FSDirectory"></see>
		/// subclass, the lock directory is automatically set to the
		/// directory itsself. Be sure to create one instance for each directory
		/// your create!
		/// </summary>
		public SimpleFSLockFactory()
		{
		}

		/// <summary>
		/// Instantiate using the provided directory (as a File instance).
		/// </summary>
		/// <param name="lockDir">where lock files should be created.</param>
		public SimpleFSLockFactory(DirectoryInfo lockDir)
		{
			SetLockDir(lockDir);
		}

		/// <summary>
		/// Instantiate using the provided directory name (String).
		/// </summary>
		/// <param name="lockDirName">where lock files should be created.</param>
		public SimpleFSLockFactory(string lockDirName)
		{
			SetLockDir(new DirectoryInfo(lockDirName));
		}

		///<summary>
		///Return a new Lock instance identified by lockName.
		///<param name="lockName">name of the lock to be created.</param>
		///</summary>
		public override ILock MakeLock(string lockName)
		{
			if (_lockPrefix != null)
			{
				lockName = _lockPrefix + "-" + lockName;
			}
			return new SimpleFSLock(_lockDir, lockName);
		}

		///<summary>
		/// Attempt to clear (forcefully unlock and remove) the
		/// specified lock.  Only call this at a time when you are
		/// certain this lock is no longer in use.
		/// <param name="lockName">name of the lock to be cleared.</param>
		/// </summary>
		public override void ClearLock(string lockName)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		///Set the lock directory. This method can be only called
		///once to initialize the lock directory. It is used by {@link FSDirectory}
		///to set the lock directory to itsself.
		///Subclasses can also use this method to set the directory
		///in the constructor.
		/// </summary>
		protected void SetLockDir(DirectoryInfo lockDir)
		{
			if (_lockDir != null)
				throw new InvalidOperationException("You can set the lock directory for this factory only once.");
			_lockDir = lockDir;
		}
	}
}